package scatter.pay.rest.service.impl;

import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import scatter.order.pojo.constant.OrderConstants;
import scatter.order.pojo.param.CreateOrderParam;
import scatter.order.pojo.po.Order;
import scatter.pay.pojo.wx.po.OrderWx;
import scatter.order.rest.service.impl.DefaultCreateOrderFrameworkServiceImpl;
import scatter.pay.rest.service.IWxOpenIdResolver;
import scatter.pay.rest.third.ThirdNotifyUrlHelper;
import scatter.pay.rest.third.WxFeeType;
import scatter.pay.rest.wx.service.IOrderWxService;

import java.util.Optional;

/**
 * <p>
 * 三方支付默认订单创建服务
 * </p>
 *
 * @author yangwei
 * @since 2021-07-03 14:15
 */
@Slf4j
public class DefaultThirdPayCreateOrderServiceImpl extends DefaultCreateOrderFrameworkServiceImpl {

	@Autowired
	private ThirdNotifyUrlHelper thirdNotifyUrlHelper;

	@Autowired
	private WxPayService wxPayService;

	@Autowired
	private IOrderWxService iOrderWxService;

	@Autowired
	private IWxOpenIdResolver iWxOpenIdResolver;


	@Override
	protected void thirdOtherOrder(CreateOrderParam param,Order order) {
		super.thirdOtherOrder(param, order);
		if (OrderConstants.OrderPayTypeDictItem.off_line_pay.itemValue().equals(param.getPayTypeDictValue())) {
			log.info("线下支付订单，不创建三方订单，直接返回");
			return;
		}

		// 判断支付类型
		// 微信支付给微信下单
		if (OrderConstants.OrderPayChannelDictItem.wx_jsapi.itemValue().equals(param.getPayChannelDictValue())) {


			ThirdNotifyUrlHelper.NotifyUrlParam notifyUrlParam = new ThirdNotifyUrlHelper.NotifyUrlParam();
			notifyUrlParam.setThirdType(ThirdNotifyUrlHelper.ThirdType.wx_pay);
			notifyUrlParam.setWxAppCode(param.getMpAppCode());
			// 请求微信
			WxPayUnifiedOrderRequest jsapi = WxPayUnifiedOrderRequest.newBuilder()
					.outTradeNo(order.getOrderNo())
					// 说id，目前没有传
					.tradeType(WxPayConstants.TradeType.JSAPI)
					.body(param.getDescription())
					.notifyUrl(thirdNotifyUrlHelper.getNotifyUrl(notifyUrlParam))
					.totalFee(param.getTotalAmount())
					.feeType(Optional.ofNullable(WxFeeType.getByCurrencyDictValue(param.getCurrencyDictValue())).map(t -> t.name()).orElse(null))
					.openid(iWxOpenIdResolver.resolve(IWxOpenIdResolver.Type.mp,param.getUserId(), param.getMpAppCode()))
					.spbillCreateIp(param.getClientIp())
					.build();

			WxPayMpOrderResult wxorder = null;
			log.info("微信jsapi下单请求参数 request={}",toJsonStr(jsapi));
			// 切换公众号
			wxPayService.switchover(param.getMpAppCode());
			try {

				wxorder = wxPayService.createOrder(jsapi);
				log.info("微信jsapi下单返回结果 result={}",toJsonStr(wxorder));
			} catch (WxPayException e) {
				throw new RuntimeException(e);
			}

			if (wxorder != null) {
				// 更新预支付id

				log.info("微信jsapi下单成功，创建微信三方订单数据");
				OrderWx orderWx = new OrderWx();
				orderWx.setOrderId(order.getId());
				orderWx.setOutTradeNo(order.getOrderNo());
				orderWx.setIsPrepayIdExpire(false);
				// 微信预支付id默认有效期两个小时，建议失效时间缓冲，在两个小时以内为宜，但一般订单失效时间建议30分钟内未支付失效
				orderWx.setPrepayIdExpireAt(param.getExpireAt());
				orderWx.setPrepayId(wxorder.getPackageValue().replace("prepay_id=",""));
				orderWx.setSpAppid(wxPayService.getConfig().getAppId());
				orderWx.setSpMchid(wxPayService.getConfig().getMchId());

				iOrderWxService.save(orderWx);
			}

		}else {
			log.warn("下单不支持的支付渠道，orderId={},payChannelDictValue={}",order.getId(),param.getPayChannelDictValue());
		}
	}
}
